<template>
  <ProTable ref="proTable" :requestApi="getList" :columns="columns" :extra-search="extraSearch" :toolButton="false">
    <!-- 表格 header 按钮 -->
    <template #tableHeader>
      <el-button type="primary" :icon="Plus" @click="openDrawer()">新增</el-button>
    </template>
    <!-- 用户状态 slot -->
    <template #status="scope">
      <!-- 如果插槽的值为 el-switch，第一次加载会默认触发 switch 的 @change 方法，所有在外层包一个盒子，点击触发盒子 click 方法 -->
      <div @click="changeStatus(scope.row)">
        <el-switch
          :value="scope.row.status"
          :active-text="scope.row.status === 1 ? '启用' : '禁用'"
          :active-value="1"
          :inactive-value="0"
        />
      </div>
    </template>
    <template #member="scope">
      <el-button type="primary" @click="memberHandle(scope.row)">组成员</el-button>
    </template>
    <!-- 表格操作 -->
    <template #operation="scope">
      <el-button type="primary" link :icon="Medal" @click="getRuleListButton(scope.row)">权限设置</el-button>
      <el-button type="primary" link :icon="EditPen" @click="doEdit(scope.row)">编辑</el-button>
      <el-button type="primary" link :icon="Delete" @click="doDelete(scope.row)">删除</el-button>
    </template>
  </ProTable>
  <el-dialog
    v-model="dialogInfo.show"
    :title="formItem.id === 0 ? '新增权限组' : '编辑权限组'"
    width="40%"
    top="30px"
    @close="doCancel(formRef)"
  >
    <el-form
      ref="formRef"
      :model="formItem"
      :rules="rules"
      label-width="120px"
      status-icon
    >
      <el-form-item label="组名称" prop="name">
        <el-input v-model="formItem.name" />
      </el-form-item>
      <el-form-item label="组描述" prop="description">
        <el-input v-model="formItem.description" type="textarea" :rows="8" />
      </el-form-item>
    </el-form>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogInfo.show = false">取消</el-button>
        <el-button type="primary" @click="submit(formRef)">确定</el-button>
      </span>
    </template>
  </el-dialog>
  <el-dialog
    v-model="dialogInfo.memberListShow"
    title="组成员列表"
    width="70%"
    top="30px"
  >
    <ProTable ref="proMemberTable" :requestApi="getUsers" :columns="memberColumns" :toolButton="false" :initParam="memberInit">
      <template #login_times="scope">
        <span>{{ scope.row.user_data ? scope.row.user_data.login_times : 0 }}</span>
      </template>
      <template #last_login_ip="scope">
        <span>{{ scope.row.user_data ? scope.row.user_data.last_login_ip : '--' }}</span>
      </template>
      <template #last_login_time="scope">
        <span>{{ scope.row.user_data ? scope.row.user_data.last_login_time : '--' }}</span>
      </template>
      <template #status_tag="scope">
        <el-tag v-if="scope.row.status === 1" type="success">启用</el-tag>
        <el-tag v-else type="danger">禁用</el-tag>
      </template>
      <template #operation="scope">
        <el-button type="danger" @click="memberDel(scope.row)">删除</el-button>
      </template>
    </ProTable>
  </el-dialog>
  <el-dialog
    v-model="dialogInfo.authListShow"
    title="权限设置"
    width="40%"
    top="30px"
  >
    <div style="height: 60vh;overflow: auto">
      <el-tree
        ref="treeRef"
        :data="authTree.dataOrigin"
        show-checkbox
        node-key="id"
        :props="{label: 'title'}"
        :default-expand-all="true"
        :default-checked-keys="authTree.defaultChecked"
      />
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogInfo.authListShow = false">取消</el-button>
        <el-button type="primary" @click="submitAuth()">确定</el-button>
      </span>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import {reactive, ref} from "vue"
import {getList, changeAuthGroupStatus, addAuth, editAuth, delAuth, delMember, getRuleList, editRule} from "@/api/modules/auth"
import {getUsers} from "@/api/modules/user";
import {Plus, EditPen, Delete, Medal} from "@element-plus/icons-vue"
import {useHandleData} from "@/hooks/useHandleData"
import {statusType} from "@/utils/serviceDict"
import {ColumnProps} from "@/components/ProTable/interface"
import ProTable from "@/components/ProTable/index.vue"
import {ElForm, ElMessage, ElTree} from "element-plus"
import {AuthItem} from "@/api/interface/auth";

type FormInstance = InstanceType<typeof ElForm>
const formRef = ref<FormInstance>()
const treeRef = ref<InstanceType<typeof ElTree>>()

const dialogInfo = reactive({
	show: false,
	memberListShow: false,
	authListShow: false
})
const proTable = ref()
const proMemberTable = ref()
const formItem = reactive<AuthItem>({
	id: 0,
	name: '',
	description: '',
	status: 1
})
const rules = reactive({
	name: [
		{required: true, message: '组名称不能为空', trigger: 'blur'}
	]
})
const memberInit = reactive({
	gid: 0
})
const authTree = reactive({
	dataOrigin: [],
	defaultChecked: []
})
const editRules = {
	rules:[],
	id: 0
}

const columns: Partial<ColumnProps>[] = [
	{
		type: "index",
		label: "#",
		width: 65
	},
	{
		prop: "name",
		label: "权限组",
		width: 200
	},
	{
		prop: "description",
		label: "描述"
	},
	{
		prop: "member",
		label: "成员授权",
		width: 116
	},
	{
		prop: "status",
		label: "状态",
		enum: statusType,
		search: true,
		searchType: 'select',
		width: 160
	},
	{
		prop: "operation",
		label: "操作",
		width: 260,
		fixed: "right"
	}
]
const extraSearch: Partial<ColumnProps>[] = [
	{
		prop: "keywords",
		label: "组名称"
	}
]
const memberColumns: Partial<ColumnProps>[] = [
	{
		type: "index",
		label: "#",
		width: 65
	},
	{
		prop: "username",
		label: "用户账号"
	},
	{
		prop: "nickname",
		label: "用户昵称",
		width: 160
	},
	{
		prop: "login_times",
		label: "登录次数",
		width: 100
	},
	{
		prop: "last_login_time",
		label: "最后登录时间",
		width: 180
	},
	{
		prop: "last_login_ip",
		label: "最后登录IP",
		width: 160
	},
	{
		prop: "status_tag",
		label: "用户状态",
		width: 100
	},
	{
		prop: "operation",
		label: "操作",
		width: 115,
		fixed: "right"
	}
]

const changeStatus = async (row: AuthItem) => {
	await useHandleData(changeAuthGroupStatus, {id: row.id, status: row.status == 1 ? 0 : 1}, `切换【${row.name}】组状态`);
	proTable.value.refresh();
}
const doDelete = async (row: AuthItem) => {
	await useHandleData(delAuth, {id: row.id}, `删除【${row.name}】组`);
	proTable.value.refresh();
}
const openDrawer = () => {
	dialogInfo.show = true
}
const doEdit = (row: AuthItem) => {
	formItem.id = Number(row.id)
	formItem.name = row.name
	formItem.description = row.description
	openDrawer()
}
const doCancel = (formEl: FormInstance | undefined) => {
	formEl?.resetFields()
	formItem.id = 0
}
const submit = (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	formEl.validate(async valid => {
		if (valid) {
			let res
			if (formItem.id === 0) {
				res = await addAuth(formItem)
			} else {
				res = await editAuth(formItem)
			}
			proTable.value.refresh()
			ElMessage.success(res.msg)
			dialogInfo.show = false
		}
	})
}

const memberHandle = (row: AuthItem) => {
	memberInit.gid = row.id
	dialogInfo.memberListShow = true
}
const memberDel = async (u: any) => {
	await useHandleData(delMember, {uid: u.id, gid: memberInit.gid}, `删除【${u.nickname}】`);
	proMemberTable.value.refresh();
}
const getRuleListButton = (row: AuthItem) => {
	editRules.id = row.id
	getRuleList({'group_id': row.id}).then(res => {
		if (res.data.list) {
			authTree.dataOrigin = res.data.list
			authTree.defaultChecked = []
			rebuildRuleShow(authTree.dataOrigin)
			if (treeRef.value) {
				treeRef.value!.setCheckedKeys(authTree.defaultChecked, false)
			}
		}
		dialogInfo.authListShow = true
	})
}

const rebuildRuleShow = (menus: any) => {
	menus.forEach((item: any) => {
		if (item.children) {
			rebuildRuleShow(item.children)
		}
		if (item.checked) {
			authTree.defaultChecked.push(item.id)
		}
	})
}

const submitAuth = () => {
	const allNodes = treeRef.value!.getCheckedNodes(false, false)
	allNodes.forEach((item) => {
		if (item.key) {
			editRules.rules.push(item.key)
		}
	})
	editRule(editRules).then(() => {
		dialogInfo.authListShow = false
		ElMessage.success('操作成功')
	})
}
</script>
